package com.service;

import static com.def.GenericDef.EVT_PNL_START_PROCESS;
import static com.def.GenericDef.E_READ_NOT_FOUND;
import static com.def.GenericDef.E_RET_PROD_INFO;
import static com.def.GenericDef.E_XPSTARTPROC_ALREAD_IN_BOX;
import static com.def.GenericDef.E_XPSTARTPROC_ALREAD_START;
import static com.def.GenericDef.E_XPSTARTPROC_INVALID_CNT;
import static com.def.GenericDef.E_XPSTARTPROC_INVALID_INPUT;
import static com.def.GenericDef.E_XPSTARTPROC_INVALID_INPUT_NO_SHT;
import static com.def.GenericDef.E_XPSTARTPROC_INVALID_STATUS;
import static com.def.GenericDef.PROC_IN_PROCESS;
import static com.def.GenericDef.RETURN_CODE_OK;
import static com.def.GenericDef.RETURN_CODE_SET_ERROR;
import static com.def.GenericDef.RETURN_CODE_UNKNOWN;
import static com.def.GenericDef.RETURN_MESG_OK;
import static com.def.GenericDef.TRX_OUT;
import static com.def.GenericDef.T_XPSTARTPROC;
import static com.def.GenericDef._NORMAL;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import com.dao.IBisOpeDao;
import com.dao.IRetBoxDao;
import com.dao.IRetPrdInfoDao;
import com.icim.service.ICIMBaseService;
import com.model.Bis_ope;
import com.model.Bis_opeId;
import com.model.Ret_prd_info;
import com.rtnBean.NotFoundRtnBeen;
import com.tx.Xpstartproc.XpstartprocI;
import com.tx.Xpstartproc.XpstartprocIA;
import com.tx.Xpstartproc.XpstartprocO;
import com.util.GUIDGenerator;
import com.util.MqOpe;
import com.util.Util;

@Scope("prototype")
@Service("XpstartprocService")
public class XpstartprocService extends ICIMBaseService{
	private static Logger logger = Logger.getLogger(XpstartprocService.class);
	private static String TX_NAME = T_XPSTARTPROC;

	private XpstartprocI inTrx;
	private XpstartprocO outTrx;
	private MqOpe mqOpe;

	private String gszMsgBuf = "";
	private Timestamp gEvtTimestamp;
	private Double gEvtTimeD;
	private String gEvtSeqID;

	@Autowired
	private IRetBoxDao retBoxDao;
	@Autowired
	private IRetPrdInfoDao retPrdInfoDao;

	@Autowired
	private XpinqcodService xpinqcodService;
	@Autowired
	private IBisOpeDao bisOpeDao;

	public String subMainProc(String strInMsg) {
		long rtnCode = _NORMAL;

		String outMsg = null;
		gszMsgBuf = "";
		gEvtTimestamp = Util.getCurrentTimestamp();
		gEvtTimeD = Util.getDoubleTime();
		gEvtSeqID = GUIDGenerator.javaGUID();
		inTrx = new XpstartprocI();
		outTrx = new XpstartprocO();
		outTrx.setTrx_id(TX_NAME);
		outTrx.setType_id(TRX_OUT);
		outTrx.setRtn_code(String.valueOf(RETURN_CODE_SET_ERROR));
		mqOpe = new MqOpe();

		try {
			inTrx = (XpstartprocI) mqOpe.inStr2Obj(strInMsg, inTrx);
			logger.info("InTrx is " + strInMsg);

			rtnCode = subMainProc2(inTrx.getAct_flg().toCharArray()[0]);
			if (rtnCode != _NORMAL) {
				TransactionAspectSupport.currentTransactionStatus()
						.setRollbackOnly();
				outTrx.setRtn_code(String.valueOf(rtnCode));
				outTrx.setRtn_mesg(gszMsgBuf);
			} else {
				outTrx.setRtn_code(String.valueOf(RETURN_CODE_OK));
				outTrx.setRtn_mesg(RETURN_MESG_OK);
				retPrdInfoDao.flushCurSession();
			}
		} catch (Exception ex) {
			TransactionAspectSupport.currentTransactionStatus()
					.setRollbackOnly();
			outTrx.setRtn_mesg(ex.toString());
			outTrx.setRtn_code(RETURN_CODE_UNKNOWN);
			logger.error(Util.stackTraceToString(ex));
		} finally {
			outMsg = mqOpe.obj2Str(outTrx);
			return outMsg;
		}
	}

	/**
	 * All move in logic
	 * 
	 * @return
	 */
	private long subMainProc2(char actionType) {
		long lRc = _NORMAL;

		switch (actionType) {
		case 'S': {
			lRc = shtStart();
			if (lRc != _NORMAL) {
				return lRc;
			}
			break;
		}
		case 'G': {
			lRc = shtStartForGroup();
			if (lRc != _NORMAL) {
				return lRc;
			}
			break;
		}
		default: {
			gszMsgBuf = "Invalide type input: [" + actionType + "]";
			return E_XPSTARTPROC_INVALID_INPUT;
		}
		}

		return lRc;
	}

	private long shtStart() {
		long lRc = _NORMAL;

		List<XpstartprocIA> iary_sht_id = new ArrayList<XpstartprocIA>();
		iary_sht_id = inTrx.getIary_sht_id();
		if (iary_sht_id.isEmpty()) {
			gszMsgBuf = "No sht in iary.";
			return E_XPSTARTPROC_INVALID_INPUT_NO_SHT;
		} else {
			for (XpstartprocIA iary : iary_sht_id) {
				Ret_prd_info prd = new Ret_prd_info();
				prd = retPrdInfoDao.get(iary.getPrd_seq_id());
				if (prd == null) {
					gszMsgBuf = new NotFoundRtnBeen(iary.getPrd_seq_id(),
							Ret_prd_info.class).toString();
					return E_RET_PROD_INFO + E_READ_NOT_FOUND;
				}

				// Prd must be INPR
				if (!PROC_IN_PROCESS.equals(prd.getPrd_stat())) {
					gszMsgBuf = "ID [" + prd.getPrd_seq_id()
							+ "]的状态是 [" + prd.getPrd_stat()
							+ "], 必须是 [" + PROC_IN_PROCESS + "]";
					return E_XPSTARTPROC_INVALID_STATUS;
				}

				// Box id must null/space
				if (!Util.isSpaceCheck(prd.getBox_id_fk())) {
					gszMsgBuf = "ID [" + prd.getPrd_seq_id()
							+ "]已经装入箱子 [" + prd.getBox_id_fk()
							+ "]";
					return E_XPSTARTPROC_ALREAD_IN_BOX;

				}

				//Begin time must null
				if (prd.getP1_timestamp() != null) {
					gszMsgBuf = "ID [" + prd.getPrd_seq_id()
							+ "] 已经开始于 [" + prd.getP1_timestamp()
							+ "]";
					return E_XPSTARTPROC_ALREAD_START;

				}

				prd.setP1_timestamp(gEvtTimestamp);
				if(prd.getCr_proc_id_fk().equals("JBZJ") || prd.getCr_proc_id_fk().equals("DMZJ")){
					prd.setP4_timestamp(gEvtTimestamp);
				}
				prd.setTool_id_fk(inTrx.getTool_id());
				prd.setCr_tool_id_fk(inTrx.getTool_id());
				if(!Util.isSpaceCheck(inTrx.getTft_buff_tool())){
					prd.setFst_judge_tool_id(inTrx.getTft_buff_tool());
				}
				if(!Util.isSpaceCheck(inTrx.getTft_buff_tool())){
					prd.setSnd_judge_tool_id(inTrx.getCf_buff_tool());
				}
				
				setProcFlgProc(prd);

				prd.setEvt_cate(EVT_PNL_START_PROCESS);
				prd.setEvt_seq_id(gEvtSeqID);
				prd.setEvt_time_d(gEvtTimeD);
				prd.setEvt_timestamp(gEvtTimestamp);
				prd.setEvt_usr(inTrx.getProcess_user());

				retPrdInfoDao.update(prd);
			}
			
			outTrx.setStart_time(gEvtTimestamp);
			outTrx.setTool_id(inTrx.getTool_id());
		}

		return lRc;
	}
	
	/**
	 * 产品批量制程开始
	 * @return
	 */
	private long shtStartForGroup() {
		long lRc = _NORMAL;
		Timestamp startTime;
		Timestamp endTime;
		List<Ret_prd_info> prdList = new ArrayList<Ret_prd_info>();
		List<Ret_prd_info> prdListNew = new ArrayList<Ret_prd_info>();
		startTime = Util.getCurrentTimestampToMilli();
		String sql = "FROM Ret_prd_info WHERE prd_seq_id in ("+ inTrx.getPrd_ids() +")";
		prdList = retPrdInfoDao.find(sql);
		if(prdList.size() != inTrx.getPrd_cnt()){
			gszMsgBuf = "部分产品代码不存在，请刷新界面！";
			return E_XPSTARTPROC_INVALID_CNT;
		}
        for(int i=0; i<prdList.size(); i++){
        	// Prd must be INPR
			Ret_prd_info retPrdInfo = prdList.get(i);
			if (!PROC_IN_PROCESS.equals(retPrdInfo.getPrd_stat())) {
				gszMsgBuf = "ID [" + retPrdInfo.getPrd_seq_id()
						+ "]的状态是 [" + retPrdInfo.getPrd_stat()
						+ "], 必须是 [" + PROC_IN_PROCESS + "]";
				return E_XPSTARTPROC_INVALID_STATUS;
			}
			// Box id must null/space
			if (!Util.isSpaceCheck(retPrdInfo.getBox_id_fk())) {
				gszMsgBuf = "ID [" + retPrdInfo.getPrd_seq_id()
						+ "]已经装入箱子 [" + retPrdInfo.getBox_id_fk()
						+ "]";
				return E_XPSTARTPROC_ALREAD_IN_BOX;
			}
			//Begin time must null
			if (retPrdInfo.getP1_timestamp() != null) {
				gszMsgBuf = "ID [" + retPrdInfo.getPrd_seq_id()
						+ "] 已经开始于 [" + retPrdInfo.getP1_timestamp()
						+ "]";
				return E_XPSTARTPROC_ALREAD_START;
			}
			retPrdInfo.setP1_timestamp(gEvtTimestamp);
			if(retPrdInfo.getCr_proc_id_fk().equals("JBZJ") || retPrdInfo.getCr_proc_id_fk().equals("DMZJ")){
				retPrdInfo.setP4_timestamp(gEvtTimestamp);
			}
			retPrdInfo.setTool_id_fk(inTrx.getTool_id());
			retPrdInfo.setCr_tool_id_fk(inTrx.getTool_id());
			if(!Util.isSpaceCheck(inTrx.getTft_buff_tool())){
				retPrdInfo.setFst_judge_tool_id(inTrx.getTft_buff_tool());
			}
			if(!Util.isSpaceCheck(inTrx.getTft_buff_tool())){
				retPrdInfo.setSnd_judge_tool_id(inTrx.getCf_buff_tool());
			}

			setProcFlgProc(retPrdInfo);
			
			retPrdInfo.setEvt_cate(EVT_PNL_START_PROCESS);
			retPrdInfo.setEvt_seq_id(gEvtSeqID);
			retPrdInfo.setEvt_time_d(gEvtTimeD);
			retPrdInfo.setEvt_timestamp(gEvtTimestamp);
			retPrdInfo.setEvt_usr(inTrx.getProcess_user());
			prdListNew.add(retPrdInfo);
        }
        retPrdInfoDao.saveOrUpdateAll(prdListNew);
		endTime = Util.getCurrentTimestampToMilli();
		logger.info("耗时（毫秒）：" + Util.getDiffMillisec(startTime, endTime));
        outTrx.setStart_time(gEvtTimestamp);
        outTrx.setTool_id(inTrx.getTool_id());
		return lRc;
	}

	private void setProcFlgProc(Ret_prd_info retPrdInfo) {
		String cr_ope_id = retPrdInfo.getCr_ope_id_fk();
		String cr_ope_ver = retPrdInfo.getCr_ope_ver_fk();
		
		Bis_opeId bis_opeId = new Bis_opeId();
		Bis_ope bis_ope = new Bis_ope();
		
		bis_opeId.setOpe_id(cr_ope_id);
		bis_opeId.setOpe_ver(cr_ope_ver);
		
		bis_ope = bisOpeDao.get(bis_opeId);
		String pep_lvl = bis_ope.getPep_lvl();
		
		int index = Integer.valueOf(pep_lvl) - 1;
		
		StringBuffer cus_sn = new StringBuffer(retPrdInfo.getCus_sn());
		int count = 0;
		try {
			count = Util.S2I(cus_sn.substring(index, index+1)) + 1;
		} catch (NumberFormatException e) {
			count = 0;
		}
		
		if (count > 1) {
			retPrdInfo.setProc_flg("N");
		}else {
			retPrdInfo.setProc_flg("Y");
		}
	}
}
